package wiki.kaizen.cloud.shiro.stateless.config;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.util.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import wiki.kaizen.cloud.shiro.stateless.properties.SecurityProperties;
import wiki.kaizen.cloud.shiro.stateless.shiro.StatelessAuthFilter;
import wiki.kaizen.cloud.shiro.stateless.shiro.AuthService;
import wiki.kaizen.cloud.shiro.stateless.util.ISecurityUtil;
import wiki.kaizen.cloud.shiro.stateless.util.JWTUtil;

import javax.annotation.PostConstruct;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
 * shiro 过滤器配置类
 * @author  xeepoo
 * */
@Configuration
public class ShiroFilterConfig {


    private final SecurityProperties securityProperties;
    private final AuthService authService;
    public ShiroFilterConfig(SecurityProperties securityProperties, AuthService authService) {
        this.securityProperties = securityProperties;
        this.authService = authService;
    }

    @PostConstruct
    public void setJwtProps(){
        JWTUtil.setProperties(securityProperties,authService);
        ISecurityUtil.setSecurityProperties(securityProperties);
    }

    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){

        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        /*
         * 设置安全管理器
         * */
        bean.setSecurityManager(securityManager);
        /*
         * 设置登录地址 权限不足地址
         * */
        SecurityProperties.SecurityFilter propFilter = securityProperties.getSecurityFilter();
        bean.setLoginUrl(propFilter.getLoginUrl());
        bean.setUnauthorizedUrl(propFilter.getUnauthorizedUrl());

        Map<String, Filter> filterMap = bean.getFilters();
        StatelessAuthFilter statelessAuthFilter = new StatelessAuthFilter();
        filterMap.put("statelessAuth",statelessAuthFilter);
        bean.setFilters(filterMap);

        Map<String, String> filterChainMap = new LinkedHashMap<>();

        filterChainMap.put(securityProperties.getAccount().getKickoutUrl(),"anon");
        filterChainMap.put(propFilter.getLockedUrl(),"anon");
        filterChainMap.put(propFilter.getLoginUrl(),"anon");
        filterChainMap.put(propFilter.getUnauthorizedUrl(),"anon");
        List<String> anons = propFilter.getAnons();
        if( anons!=null &&anons.size()>0 ){
            anons.forEach(
                anon-> {
                    if (StringUtils.hasLength(anon)){
                        filterChainMap.put(anon,"anon");
                    }
                }
            );
        }

        List<String> authcs = propFilter.getAuthcs();
        if( authcs!=null &&authcs.size()>0 ){
            authcs.forEach(
                authc-> {
                    if (StringUtils.hasLength(authc)){
                        filterChainMap.put(authc,"authc");
                    }
                }
            );
        }

        filterChainMap.put("/**","statelessAuth");
        bean.setFilterChainDefinitionMap(filterChainMap);

        return bean;
    }

}
